/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.qiujuer.genius.ui.drawable.shape;

import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.Path;
import ohos.agp.render.PathEffect;
import ohos.agp.utils.Rect;

/**
 * This class is draw line on border
 * Line is support dash line
 * This class is extend shape
 * Use to ShapeDrawable class
 *
 * @since 2021-05-12
 */
public class BorderShape extends Shape {
    private Rect mBorder = null;
    private PathEffect mPathEffect = null;
    private Path mPath = null;

    /**
     * constructor
     *
     * @param border
     */
    public BorderShape(Rect border) {
        this(border, 0, 0);
    }

    /**
     * constructor
     *
     * @param border
     * @param dashWidth
     * @param dashGap
     */
    public BorderShape(Rect border, float dashWidth, float dashGap) {
        if (border.left != 0 || border.top != 0 || border.right != 0 || border.bottom != 0) {
            mBorder = border;
            if (dashWidth > 0 && dashGap > 0) {
                mPathEffect = new PathEffect(new float[]{dashWidth, dashGap}, 0);
                mPath = new Path();
            }
        }
    }

    /**
     * set border
     *
     * @param border
     */
    public void setBorder(Rect border) {
        if (border.left != 0 || border.top != 0 || border.right != 0 || border.bottom != 0) {
            if (mBorder == null) {
                mBorder = new Rect(border);
            } else {
                mBorder.set(border.left, border.top, border.right, border.bottom);
            }
        } else {
            this.mBorder = null;
        }
    }

    /**
     * get border
     *
     * @param border
     * @return rect
     */
    public Rect getBorder(Rect border) {
        if (mBorder != null && border != null) {
            border.set(mBorder.left, mBorder.top, mBorder.right, mBorder.bottom);
        }
        return border;
    }

    /**
     * draw
     *
     * @param canvas the Canvas within which this shape should be drawn
     * @param paint the Paint object that defines this shape's characteristics
     */
    @SuppressWarnings("SuspiciousNameCombination")
    @Override
    public void draw(Canvas canvas, Paint paint) {
        if (mBorder == null) {
            return;
        }
        float width = getWidth();
        float height = getHeight();
        if (mPathEffect == null) {
            if (mBorder.left > 0) {
                canvas.drawRect(0, 0, mBorder.left, height, paint);
            }
            if (mBorder.top > 0) {
                canvas.drawRect(0, 0, width, mBorder.top, paint);
            }
            if (mBorder.right > 0) {
                canvas.drawRect(width - mBorder.right, 0, width, height, paint);
            }
            if (mBorder.bottom > 0) {
                canvas.drawRect(0, height - mBorder.bottom, width, height, paint);
            }
        } else {
            if (paint.getPathEffect() != mPathEffect) {
                paint.setStyle(Paint.Style.STROKE_STYLE);
                paint.setPathEffect(mPathEffect);
            }
            if (mBorder.left > 0) {
                paint.setStrokeWidth(mBorder.left);
                initPath(mBorder.left / 2.f, 0, mBorder.left / 2.f, height);
                canvas.drawPath(mPath, paint);
            }
            if (mBorder.top > 0) {
                paint.setStrokeWidth(mBorder.top);
                initPath(0, mBorder.top / 2.0f, width, mBorder.top / 2.0f);
                canvas.drawPath(mPath, paint);
            }
            if (mBorder.right > 0) {
                paint.setStrokeWidth(mBorder.right);
                initPath(width - mBorder.right / 2.0f, 0, width - mBorder.right / 2.0f, height);
                canvas.drawPath(mPath, paint);
            }
            if (mBorder.bottom > 0) {
                paint.setStrokeWidth(mBorder.bottom);
                initPath(0, (int)height - mBorder.bottom / 2, width, (int)height - mBorder.bottom / 2);
                canvas.drawPath(mPath, paint);
            }
        }
    }

    private void initPath(float startX, float startY, float endX, float endY) {
        mPath.reset();
        mPath.moveTo(startX, startY);
        mPath.lineTo(endX, endY);
    }
}
